package com.dospyer.redisson;

import org.redisson.Redisson;
import org.redisson.RedissonMultiLock;
import org.redisson.api.*;
import org.redisson.config.Config;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Application {

    public static void main(String[] args) throws Exception {
        Config config = new Config();
        config.useSentinelServers()
                .setDatabase(1)
                .setPassword("ItrusPassTest2019##")
                .setMasterName("mymaster")
                .addSentinelAddress("redis://192.168.100.120:26379", "redis://192.168.100.120:26380", "redis://192.168.100.120:26381");

//        config.useClusterServers()
//                .addNodeAddress("redis://192.168.31.114:7001")
//                .addNodeAddress("redis://192.168.31.114:7002")
//                .addNodeAddress("redis://192.168.31.114:7003")
//                .addNodeAddress("redis://192.168.31.184:7001")
//                .addNodeAddress("redis://192.168.31.184:7002")
//                .addNodeAddress("redis://192.168.31.184:7003");

        RedissonClient redisson = Redisson.create(config);

        try{
            //保存数据
//            saveData(redisson);

            // 可重入锁
//            reentantLock(redisson);

            // 公平锁
            fairLock(redisson);

            // multiLock
//            multiLock(redisson);

            // 读写锁
//            readWriteLock(redisson);

            // semaphoreDemo
//            semaphoreDemo(redisson);

            // countDownLatch
//            countDownLatchDemo(redisson);
        } finally {
            redisson.shutdown();
        }
    }

    /**
     * 读写锁
     *
     * @param redisson
     */
    private static void readWriteLock(RedissonClient redisson) {
        RReadWriteLock readWriteLock = redisson.getReadWriteLock("anyLock");
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        rLock.unlock();

        RLock wLock = readWriteLock.writeLock();
        wLock.lock();
        wLock.unlock();
    }

    /**
     * multiLock
     *
     * @param redisson
     */
    private static void multiLock(RedissonClient redisson) {
        RLock lock1 = redisson.getLock("lock1");
        RLock lock2 = redisson.getLock("lock2");
        RLock lock3 = redisson.getLock("lock3");

        RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2, lock3);
        multiLock.lock();
        multiLock.unlock();
    }

    /**
     * 公平锁
     *
     * @param redisson
     */
    private static void fairLock(RedissonClient redisson) {
        RLock lock = redisson.getFairLock("anyLock");
        lock.lock();
        try {
            boolean b = lock.tryLock(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        lock.unlock();
    }

    /**
     * 可重入锁
     *
     * @param redisson
     */
    private static void reentantLock(RedissonClient redisson) {
        RLock lock = redisson.getLock("anyLock");
        lock.lock();
        lock.unlock();
    }

    private static void saveData(RedissonClient redisson) {
        // 保存数据
        RMap<String, Object> map = redisson.getMap("anyMap");
        map.put("foo", "bar");

        map = redisson.getMap("anyMap");
        System.out.println(map.get("foo"));
    }

    private static void semaphoreDemo(RedissonClient redisson) {
        RSemaphore semaphore = redisson.getSemaphore("semaphore");
        semaphore.trySetPermits(3);

        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]尝试获取Semaphore锁");
                        semaphore.acquire();
                        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]成功获取到了Semaphore锁，开始工作");
                        Thread.sleep(3000);
                        semaphore.release();
                        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]释放Semaphore锁");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }).start();
        }
    }

    private static void countDownLatchDemo(final RedissonClient redisson) throws InterruptedException {
        RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
        latch.trySetCount(3);
        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]设置了必须有3个线程执行countDown，进入等待中。。。");

        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]在做一些操作，请耐心等待。。。。。。");
                        Thread.sleep(3000);
                        RCountDownLatch localLatch = redisson.getCountDownLatch("anyCountDownLatch");
                        localLatch.countDown();
                        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]执行countDown操作");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }).start();
        }

        latch.await();
        System.out.println(new Date() + "：线程[" + Thread.currentThread().getName() + "]收到通知，有3个线程都执行了countDown操作，可以继续往下走");
    }

}
